#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <png.h>
#include <photo_manager.h>
#include <config.h>

static int pngIsSupport(char *filename);
static int pngGetDispData(char *filename, PT_imageInfo image);

static T_PhotoOpr pngOpr = 
{
	.name 			= "png",
	.isSupport 		= pngIsSupport,
	.getDispData 	= pngGetDispData,
	.next 			= NULL,
};

static int pngIsSupport(char *filename)
{
	if(filename ==NULL)
	{
		fprintf(stderr, "the parama error\n");
		return 0;
	}

	if(strstr(filename, ".png")==NULL)
	{
		return 0;
	}
	else
		return 1;

	return 0;
}

/*
//处理透明图片方法
//得到图片颜色
r=row_pointers[i][j + 0];
g=row_pointers[i][j + 1];
b=row_pointers[i][j + 2];
a=row_pointers[i][j + 3];
		
//读取当前屏幕点的背景颜色
b_rgb24=LCD_ReadPoint(x0,y);
b_r=b_rgb24>>16&0xFF;
b_g=b_rgb24>>8&0xFF;
b_b=b_rgb24>>0&0xFF;
		
//合成屏幕背景颜色
R = (unsigned char)(r * (a / 255.0) + (b_r * (255 - a)) / 255.0);
G = (unsigned char)(g * (a / 255.0) + (b_g * (255 - a)) / 255.0);
B = (unsigned char)(b * (a / 255.0) + (b_b * (255 - a)) / 255.0);
	 
//显示数据
rgb24=R<<16|G<<8|B;
LCD_DrawPoint(x0,y,rgb24);
*/

static int pngGetDispData(char *filename, PT_imageInfo image)
{
	FILE *fp;
	png_structp png_ptr;
	png_infop info_ptr;
	png_uint_32 width, height;
	png_bytep* row_ptr;  //实际存储rgb数据的buf，二维指针
	png_byte bit_depth;
	png_uint_32 color_type;
	int i,j,pos=0;
	unsigned char *buff;

   	if ((fp = fopen(filename, "rb")) == NULL)
   	{
      	fprintf(stderr, "open %s failed\n", filename);
      	return -1;
   	}

   /* Create and initialize the png_struct with the desired error handler
    * functions.  If you want to use the default stderr and longjump method,
    * you can supply NULL for the last three parameters.  We also supply the
    * the compiler header file version, so that we know if the application
    * was compiled with a compatible version of the library.  REQUIRED
    */
   	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

   	if (png_ptr == NULL)
   	{
      	fclose(fp);
      	return -1;
  	}

   	/* Allocate/initialize the memory for image information.  REQUIRED. */
   	info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL)
	{
		fclose(fp);
		png_destroy_read_struct(&png_ptr, NULL, NULL);
		return -1;
	}

	//第2步：设置错误返回点	
	if (setjmp(png_jmpbuf(png_ptr)))
	{
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		fclose(fp);
		return -1;
	}
	
    /* One of the following I/O initialization methods is REQUIRED */
    /* Set up the input control if you are using standard C streams */
    png_init_io(png_ptr, fp);
  	png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_ALPHA, NULL); 
//	png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, NULL); 

  	width 		= png_get_image_width( png_ptr, info_ptr );
   	height 		= png_get_image_height( png_ptr, info_ptr );
	bit_depth 	= png_get_bit_depth(png_ptr, info_ptr);
    color_type 	= png_get_color_type(png_ptr, info_ptr);

	buff = malloc(width*height*3);
	if(buff ==NULL)
	{
		fprintf(stdout,"malloc error\n");
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
		fclose(fp);
		return -1;
	}
 
	// 第6步: 读取真正的图像信息
	row_ptr = png_get_rows(png_ptr, info_ptr);
	switch (color_type) 
	{
		case PNG_COLOR_TYPE_RGB_ALPHA:
			for (i = 0; i < height; i++) 
			{
				for (j = 0; j < width*4; j+=4) 
				{
					buff[pos++] = row_ptr[i][j+0];
					buff[pos++] = row_ptr[i][j+1];
					buff[pos++] = row_ptr[i][j+2];
				}
			}
			break;
		case PNG_COLOR_TYPE_RGB:
			for (i = 0; i < height; i++) 
			{
				for (j = 0; j < width*3; j+=3) 
				{
					buff[pos++] = row_ptr[i][j+0];
					buff[pos++] = row_ptr[i][j+1];
					buff[pos++] = row_ptr[i][j+2];
				}
			}
			break;
		default:
			break;	
	}

	image->height 			= height;
	image->width 			= width;
	image->iBpp 			= bit_depth*3;
	image->isBMP 			= 0;
	image->imageDataBuff 	= buff;

    /* Clean up after the read, and free any memory allocated - REQUIRED */
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

    /* Close the file */
    fclose(fp);

    /* That's it */
    return 0;
}

int pngInit(void)
{
	int ret;

	ret = registerPhotoOpr(&pngOpr);
	return ret;
}

